package vn.demand.dragon.view
{
	import com.salesbuilder.control.TabManager;
	import com.salesbuilder.controls.DateField;
	
	import flash.events.ContextMenuEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	import flash.ui.Keyboard;
	
	import flexed.widgets.alerts.alert;
	
	import mx.collections.ICollectionView;
	import mx.collections.IViewCursor;
	import mx.controls.AdvancedDataGrid;
	import mx.controls.Alert;
	import mx.controls.Button;
	import mx.controls.NumericStepper;
	import mx.controls.TextInput;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridItemRenderer;
	import mx.core.UIComponent;
	import mx.events.AdvancedDataGridEvent;
	import mx.events.AdvancedDataGridEventReason;
	import mx.events.CloseEvent;
	import mx.events.FlexEvent;
	import mx.events.ValidationResultEvent;
	import mx.formatters.DateFormatter;
	import mx.managers.PopUpManager;
	import mx.validators.Validator;
	
	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;
	
	import vn.demand.dragon.CommonCommand;
	import vn.demand.dragon.FFIAApplicationFacade;
	import vn.demand.dragon.editor.EditorComboBox;
	import vn.demand.dragon.model.MasterdataProxy;
	import vn.demand.dragon.model.TaskLogProxy;
	import vn.demand.dragon.model.UserProxy;
	import vn.demand.dragon.view.components.ItemCompleteDialog;
	import vn.demand.dragon.view.components.TaskLogScreen;
	import vn.demand.utils.DpUtils;


	public class TaskLogScreenMediator extends Mediator
	{
		public static const NAME:String = "TaskLogScreenMediator";
		
		private var masterdataProxy:MasterdataProxy;
		private var taskLogProxy:TaskLogProxy;
		private var userProxy:UserProxy;
		
		private var projectVO:Object;
		
		public static function makeId(projectVO:Object, singleton:Boolean = false):String {
			if (singleton) {
				return NAME;
			}
        	return NAME + projectVO.project_id + "::";
        }
		
		public function TaskLogScreenMediator(projectVO:Object, mediatorName:String, viewComponent:Object)
		{
			super(mediatorName, viewComponent);
			
			this.projectVO = projectVO;
			
			masterdataProxy = facade.retrieveProxy(MasterdataProxy.NAME) as MasterdataProxy;
			taskLogProxy = facade.retrieveProxy(TaskLogProxy.NAME) as TaskLogProxy;
			userProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;
			
			taskLogScreen.addEventListener(TaskLogScreen.TASK_LOG_SCREEN_UI_CREATED, prepareData);
		}
		
		public function prepareData(event:Event):void {
			for each (var col:AdvancedDataGridColumn in gridTaskLog.groupedColumns) {
				switch (col.dataField) {					
					case 'task_log_resource':
					case 'task_log_item':
					case 'task_log_currency':
					case 'task_log_expense':
						col.labelFunction = comboBoxLabelFunction;
						break;
					case 'task_log_date':
						col.labelFunction = lfTaskLogDate;
						break;
					case 'line_no':
						col.labelFunction = lfRowNum;
						break;
					case 'task_log_is_complete':
						col.labelFunction = lfTaskLogComplete;
						break;
				}
			}
			
			gridTaskLog.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_BEGIN, makeEditor);
			gridTaskLog.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_END, processData);
			
			taskLogScreen.addEventListener(TaskLogScreen.SAVE_TASK_LOG, onSaveTaskLog);
			taskLogScreen.addEventListener(TaskLogScreen.RELOAD_TASK_LOG, onReloadTaskLog);
			taskLogScreen.addEventListener(TaskLogScreen.BROWSE_REFERENCE, onBrowseReference);
			taskLogScreen.addEventListener(TaskLogScreen.REMOVE_TASK_LOG, onRemoveTask);
			taskLogScreen.addEventListener(TaskLogScreen.CLOSE_TASK_LOG, onCloseForm);
			taskLogScreen.addEventListener(TaskLogScreen.COMPLETE_ALL_TASK_LOG, onCompleteAll);
			
			createContextMenu();
			
			gridTaskLog.contextMenu = m;
			
			doLoadTaskLog();
			
			var canEdit:Boolean = DpUtils.isTrue(userProxy.userInfo.task_edit);
			if (!canEdit || masterdataProxy.isProjectProcessed(this.projectVO)) {
				taskLogScreen.canEdit = false;
				removeMenu.enabled = false;
			}
		}
		
		public function doLoadTaskLog():void {
			taskLogProxy.loadTaskLogByReference();
		}
		
		public function onCompleteAll(event:Event):void {
			var errors:String = "";
			var hasTaskForComplete:Boolean = false;
			for(var i=0; i < gridTaskLog.dataProvider.length; i++) {
				var sel = gridTaskLog.dataProvider.getItemAt(i);
				if (DpUtils.isTrue(sel.task_log_is_complete)) {
					continue;
				}
				if (Number(sel.task_log_item) == 0) {
    				continue;
	        	}
				hasTaskForComplete = true; 
	        	if (Number(sel.task_log_expense) == 3) {
	    			errors += 'Row [' + i + ']: You can not complete task log whose expense type is Other \n';
	    		}
	        	errors += validateItem(sel, i);
			}
			if (!hasTaskForComplete) {
				alert.error('There are no task logs for completing!');
				return;
			}
			if (errors.length > 0) {
				alert.error('You can not complete all task log. There are errors: \n' + errors);
				return;
			}
			var dialog:ItemCompleteDialog = PopUpManager.createPopUp(taskLogScreen, ItemCompleteDialog, true) as ItemCompleteDialog;
			PopUpManager.centerPopUp(dialog);
			dialog.title = "Do you want to complete all these task logs?";
			dialog.completed_date.selectedDate = new Date();
			dialog.caller = this;
			dialog.callback = confirmCompleteAllTask;
		}
		
		public function onRemoveTask(event:Event):void {
			doRemoveTaskLog(gridTaskLog.selectedIndex);
		}
		
		public function onBrowseReference(event:Event) {
			sendNotification(FFIAApplicationFacade.BROWSE_REFERENCE_LIST);
		}
		
		private function onCloseForm(event:Event):void {
			if (taskLogScreen.enableSave) {
				alert.confirm("Do you want to save before close?", handleConfirmSave, Alert.CANCEL);
			} else {
				beingClose = true;
				doClose();
			}
        }
        
        public var beingClose:Boolean = false;
        private function handleConfirmSave(event:CloseEvent) {
        	beingClose = true;
        	if (event.detail == Alert.CANCEL) {
        		return;
        	}
        	if (!doSaveTaskLog()) {
        		beingClose = false;
        	}
        	if (beingClose) {
        		doClose();        		
        	}
        }
        
        private function handleConfirmSaveBeforeLoadAnother(event:CloseEvent) {
        	if (event.detail == Alert.CANCEL) {
	        	sendNotification(CommonCommand.CANCEL_FOR_LOAD_REFERENCE, projectVO, NAME);
        		return;
        	}
        	if (event.detail == Alert.YES) {
        		if (!doSaveTaskLog()) {
	        		sendNotification(CommonCommand.CANCEL_FOR_LOAD_REFERENCE, projectVO, NAME);
	        		return;
        		}
        	}
    		gridTaskLog.dataProvider = null;
			taskLogScreen.enableSave = false;
    		sendNotification(CommonCommand.OK_FOR_LOAD_REFERENCE, projectVO, NAME);
        }
        
        private function doClose():void {
        	TabManager.removeTab(taskLogScreen);
        	sendNotification(CommonCommand.CLOSE_FINISH_PROJECT_TASK_LOGS_PANEL, projectVO);	
        }
		
		var m:ContextMenu;
		var copyMenu:ContextMenuItem;
        var pasteMenu:ContextMenuItem;
        var removeMenu:ContextMenuItem;
        
        private function createContextMenu():void {
		    m = new ContextMenu();
		    m.hideBuiltInItems();
		    var customItemsArr:Array = new Array();
		    copyMenu = new ContextMenuItem("Copy Row");
		    pasteMenu = new ContextMenuItem("Patse Row");
		    removeMenu = new ContextMenuItem("Remove Row");
		    
		    copyMenu.addEventListener("menuItemSelect", copyHandler);
		    pasteMenu.addEventListener("menuItemSelect", pasteHandler);
		    removeMenu.addEventListener("menuItemSelect", removeHandler);
		    
		    pasteMenu.enabled = false;
		    
		    customItemsArr.push(copyMenu);
		    customItemsArr.push(pasteMenu);
		    customItemsArr.push(removeMenu);
		    
		    m.customItems = customItemsArr;
	    }
	    
	    private var copyItem:Object = null;
	    
	    private function copyHandler(e:ContextMenuEvent):void
	    {
	    	var itemIndex:Number = -1;
	    	if (e.mouseTarget is AdvancedDataGridItemRenderer) {
		    	itemIndex = AdvancedDataGridItemRenderer(e.mouseTarget).listData.rowIndex;
	    	} else {
	    		itemIndex = gridTaskLog.selectedIndex;
	    	}
	    	if (itemIndex < 0) return;
	    	pasteMenu.enabled = true;	    	
		    copyItem = gridTaskLog.dataProvider.getItemAt(itemIndex);
	    }
	    
	    private function pasteHandler(e:ContextMenuEvent):void
	    {
	    	if (masterdataProxy.isProjectProcessed(projectVO)) {
	    		return;
	    	}
	    	
		    var itemIndex:Number = -1;
	    	if (e.mouseTarget is AdvancedDataGridItemRenderer) {
		    	itemIndex = AdvancedDataGridItemRenderer(e.mouseTarget).listData.rowIndex;
	    	} else {
	    		itemIndex = gridTaskLog.selectedIndex;
	    	}
	    	if (itemIndex < 0) return;
	    	taskLogProxy.copyTaskLog(projectVO, copyItem, itemIndex);
	    	taskLogScreen.enableSave = true;
	    }
	    
	    private function removeHandler(e:ContextMenuEvent):void
	    {
	    	if (masterdataProxy.isProjectProcessed(projectVO)) {
	    		return;
	    	}
	    	var itemIndex:Number = -1;
	    	if (e.mouseTarget is AdvancedDataGridItemRenderer) {
		    	itemIndex = AdvancedDataGridItemRenderer(e.mouseTarget).listData.rowIndex;
	    	} else {
	    		itemIndex = gridTaskLog.selectedIndex;
	    	}
	    	if (itemIndex < 0) {
	    		alert.error("You don't select any row to remove!");
	    		return;
	    	}
		    doRemoveTaskLog(itemIndex);
	    }
		
		function onSaveTaskLog(event:Event):void {
			if (doSaveTaskLog()) {
				sendNotification(FFIAApplicationFacade.TASK_LOG_UPDATED);
			};
		}
		
		function doSaveTaskLog():Boolean {
			if (!doValidate()) {
				alert.error(gridTaskLog.errorString);
				return false;
			}
			taskLogScreen.enableSave = false;
			
			var cursor:IViewCursor = ICollectionView(gridTaskLog.dataProvider).createCursor();
        	while (!cursor.afterLast) {
        		if ((Number(cursor.current['task_log_item']) <= 0)) {
        			cursor.remove();
        		} else {
        			cursor.moveNext();
        		}
        	} 
			
			taskLogProxy.saveTaskLog();
			return true;
		}
		
		function onReloadTaskLog(event:Event):void {
			if (taskLogScreen.enableSave) {
	        	alert.confirm("Data has being edited, do you want to reload?", function(e:CloseEvent) {
	        		if (e.detail == Alert.YES) {
	        			sendNotification(FFIAApplicationFacade.REFRESH_PROJECT_TASK_LOG, null, projectVO.project_id);	        			
	        		}
	        	});
        	} else {
        		sendNotification(FFIAApplicationFacade.REFRESH_PROJECT_TASK_LOG, null, projectVO.project_id);
        	}			
		}
		
		public function get taskLogScreen():TaskLogScreen
		{
            return viewComponent as TaskLogScreen;
        }
        
        public function get gridTaskLog():AdvancedDataGrid {
			return taskLogScreen.gridTaskLog;
		}
		
		public function doValidate():Boolean {
        	var errors:String = "";
        	var i:int = 1;
        	for each (var item:Object in gridTaskLog.dataProvider) {
        		if (Number(item.task_log_item) <= 0) {
        			continue;
        		}
        		errors += validateItem(item, i);
        		i++;
        	}
        	if (errors.length > 0) {
        		gridTaskLog.errorString = errors;
        		return false;
        	}
    		gridTaskLog.errorString = "";
    		return true;
        }
        
		/**
         * List all notifications this Mediator is interested in.
         * <P>
         * Automatically called by the framework when the mediator
         * is registered with the view.</P>
         * 
         * @return Array the list of Nofitication names
         */
        override public function listNotificationInterests():Array 
        {
            return [ 
            	CommonCommand.CLOSE_TAB,
            	FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_SUCCESS,
            	FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_FAILED,
            	FFIAApplicationFacade.REFERENCE_SELECTED,
            	FFIAApplicationFacade.LOAD_MASTERDATA_SUCCESS,
            	FFIAApplicationFacade.LOAD_MASTERDATA_FAILED,
            	FFIAApplicationFacade.LOAD_TASK_LOG_BY_REFERENCE_FAILED,
            	FFIAApplicationFacade.LOAD_TASK_LOG_BY_REFERENCE_SUCCESS,
            	FFIAApplicationFacade.TASK_LOG_UPDATED,
            	FFIAApplicationFacade.TASK_LOG_UPDATE_FAILED,
            	FFIAApplicationFacade.REFRESH_PROJECT_TASK_LOG,
            	CommonCommand.BEFORE_LOAD_REFERENCE
			];
        }
        
        /**
         * Handle all notifications this Mediator is interested in.
         * <P>
         * Called by the framework when a notification is sent that
         * this mediator expressed an interest in when registered
         * (see <code>listNotificationInterests</code>.</P>
         * 
         * @param INotification a notification 
         */
        override public function handleNotification( note:INotification ):void 
        {
        	RIALogger.debug(this, "handleNotification: " + Number(projectVO.project_id));
            switch ( note.getName() ) 
			{
				case CommonCommand.CLOSE_TAB:
					if (note.getBody() == taskLogScreen) {
						onCloseForm(new Event('onCloseTask'));
					}
					break;
				case FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_SUCCESS:
					if (note.getType() != NAME) {
						return;
					}
					this.projectVO = note.getBody();
					
					taskLogProxy.reinit(projectVO);
					taskLogProxy.tasklogDP.addItem(taskLogProxy.newTaskLog());
                	gridTaskLog.dataProvider = taskLogProxy.tasklogDP;
					
					RIALogger.debug(this, "doLoadTaskLogs after load in project navigation");
					this.doLoadTaskLog();
					if (masterdataProxy.isProjectProcessed(this.projectVO)) {
						taskLogScreen.canEdit = false;
						removeMenu.enabled = false;
					} else {
						taskLogScreen.canEdit = true;
						removeMenu.enabled = true;
					}
					break;
				case FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_FAILED:
					break;
                case FFIAApplicationFacade.LOAD_TASK_LOG_BY_REFERENCE_SUCCESS:
		            if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
                	taskLogProxy.tasklogDP.addItem(taskLogProxy.newTaskLog());
                	gridTaskLog.dataProvider = taskLogProxy.tasklogDP;
                	gridTaskLog.errorString = null;
                	taskLogScreen.enableSave = false;
                	break;
				
				case FFIAApplicationFacade.LOAD_TASK_LOG_BY_REFERENCE_FAILED:
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
                	taskLogScreen.gridTaskLog.errorString = note.getBody().toString();
                	break;
				
				case FFIAApplicationFacade.TASK_LOG_UPDATED:
					if (beingClose) {
						return;
					}
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
					alert.info("Task logs updated");
					taskLogProxy.tasklogDP.addItem(taskLogProxy.newTaskLog());
					break;
				case FFIAApplicationFacade.TASK_LOG_UPDATE_FAILED:
					if (beingClose) {
						return;
					}
					alert.error(note.getBody() as String);
					taskLogProxy.tasklogDP.addItem(taskLogProxy.newTaskLog());
					break;
				case FFIAApplicationFacade.REFRESH_PROJECT_TASK_LOG:
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
					doLoadTaskLog();
					break;
				case CommonCommand.BEFORE_LOAD_REFERENCE:
					if (note.getType() != NAME) {
						return;
					}
					if (taskLogScreen.enableSave) {
						alert.confirm("Do you want to save before load another Reference?", handleConfirmSaveBeforeLoadAnother, Alert.CANCEL);
					} else {
						gridTaskLog.dataProvider = null;
						taskLogScreen.enableSave = false;
						sendNotification(CommonCommand.OK_FOR_LOAD_REFERENCE, projectVO, NAME);
					}
					break;
            }
        }       
        			
        public function makeEditor(event:AdvancedDataGridEvent):void {				
			var columnName:String = gridTaskLog.columns[event.columnIndex].dataField;
			var sel:Object = gridTaskLog.dataProvider.getItemAt(gridTaskLog.selectedIndex);
			if (DpUtils.isTrue(sel.task_log_is_complete)) {
				event.preventDefault();
				return;
			}
			var itemEditor:UIComponent = null;
			event.preventDefault();
			gridTaskLog.createItemEditor(event.columnIndex, event.rowIndex);
	        itemEditor = gridTaskLog.itemEditorInstance as UIComponent;
			var value:String = "" + gridTaskLog.editedItemRenderer.data[columnName];
			switch(columnName) {
				case 'task_log_resource':
					var cb:EditorComboBox = EditorComboBox(itemEditor);
					cb.dataProvider = masterdataProxy.usersDP;
					cb.selectedData = Number(value);
					break;
				case 'task_log_item':
					var cb:EditorComboBox = EditorComboBox(itemEditor);
					cb.dataProvider = masterdataProxy.taskLogItemsDP;
					cb.selectedData = Number(value);
					break;
				case 'task_log_currency':
					var cb:EditorComboBox = EditorComboBox(itemEditor);
					cb.dataProvider = masterdataProxy.currenciesDP;
					cb.selectedData = Number(value);
					break;
				case 'task_log_expense':
					var cb:EditorComboBox = EditorComboBox(itemEditor);
					cb.dataProvider = masterdataProxy.expenseTypeDP;
					cb.selectedData = Number(value);
					break;
				case 'task_log_date':
	                DateField(itemEditor).selectedDate = DpUtils.parseDate(value);
					break;
				case 'task_percent_complete':
					NumericStepper(itemEditor).minimum = 0;
					NumericStepper(itemEditor).maximum = 100;
					if (Number(value) == 0 || Number(value) == NaN) {
						NumericStepper(itemEditor).data = 100
					} else {
						NumericStepper(itemEditor).data = Number(value);
					}
					break;
				case 'task_log_from':
				case 'task_log_currency':
				case 'task_log_amount_origin':
				case 'task_log_exchange_rate':
				case 'task_log_from':
				case 'task_log_to':
				case 'task_log_distance':
				case 'task_log_truck_no':
				case 'task_log_driver':
				case 'task_log_fuel':
				case 'task_log_description':
					TextInput(itemEditor).text = value;
					TextInput(itemEditor).selectionBeginIndex = 0;
					TextInput(itemEditor).selectionEndIndex = String(value).length;
					break;
				case 'task_log_is_complete':
					event.preventDefault();
	                gridTaskLog.createItemEditor(event.columnIndex, event.rowIndex);
	                var value = gridTaskLog.editedItemRenderer.data[columnName];
	                Button(gridTaskLog.itemEditorInstance).label = "Complete";
	                Button(gridTaskLog.itemEditorInstance).width = 100;
	                Button(gridTaskLog.itemEditorInstance).addEventListener(FlexEvent.BUTTON_DOWN, handleCompleteTask);
	                Button(gridTaskLog.itemEditorInstance).setFocus();
	                return;
				default:
					break;
			}
            
            if (itemEditor is EditorComboBox) {
            	
            }
            else {
	            UIComponent(gridTaskLog.itemEditorInstance).addEventListener(KeyboardEvent.KEY_DOWN, handleKeyArrow);
            }
            
            setupValidator(columnName, gridTaskLog.itemEditorInstance);
            
	        UIComponent(gridTaskLog.itemEditorInstance).setFocus();
        }
        
        public function handleKeyArrow(event:KeyboardEvent):void {
        	if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP) {
        		event.stopPropagation();
            	var newEvent:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, false, false, Keyboard.ENTER, Keyboard.ENTER, 13, event.ctrlKey, event.altKey, event.keyCode == Keyboard.UP);
            	var b:Boolean = event.currentTarget.dispatchEvent(newEvent);
        	}            	
        }
        
        public function handleCompleteTask(event:FlexEvent):void {
    		var sel:Object = gridTaskLog.dataProvider.getItemAt(gridTaskLog.selectedIndex);
    		var errors:String = "";
        	var i:int = gridTaskLog.selectedIndex + 1
        	if (Number(sel.task_log_item) == 0) {
    			errors += 'Row [' + i + ']: Activity can not be empty\n';
        	}
        	if (Number(sel.task_log_expense) == 3) {
    			errors += 'Row [' + i + ']: You can not complete task log whose expense type is Other \n';
    		}
        	errors += validateItem(sel, i);
    		if (errors.length > 0) {
        		alert.error(errors);
    		} else {
    			var dialog:ItemCompleteDialog = PopUpManager.createPopUp(taskLogScreen, ItemCompleteDialog, true) as ItemCompleteDialog;
    			PopUpManager.centerPopUp(dialog);
    			dialog.title = "Do you want to complete this task log?";
    			dialog.completed_date.selectedDate = new Date();
    			dialog.caller = this;
    			dialog.callback = confirmCompleteTask;
    		}
        }
        
        public function validateItem(item:Object, i:int):String {
        	var errors:String = '';
        	if (Number(item.task_log_resource) <= 0) {
        		errors += 'Row [' + i + ']: Resource can not be empty\n';
    		}
    		if (Number(item.task_log_currency) <= 0) {
    			errors += 'Row [' + i + ']: Currency can not be empty\n';
    		}
    		if (Number(item.task_log_expense) <= 0) {
    			errors += 'Row [' + i + ']: Expense Type can not be empty\n';
    		}
    		if (Number(item.task_log_amount_origin) <= 0 || Number(item.task_log_amount_origin) == NaN) {
    			errors += 'Row [' + i + ']: Expense Amount can not be empty\n';
    		}
    		if (Number(item.task_log_currency) == 2 && 
    			(Number(item.task_log_exchange_rate) == 0 || 
    			Number(item.task_log_exchange_rate) == NaN))
    		{
    			errors += 'Row [' + i + ']: Exchange Rate can not be empty\n';
    		}
    		return errors;
        }
        
        public function confirmCompleteAllTask(event:CloseEvent, completedDate:String):void {
        	var errors:String = "";
			for(var i=0; i < gridTaskLog.dataProvider.length; i++) {
				var sel = gridTaskLog.dataProvider.getItemAt(i);
				if (DpUtils.isTrue(sel.task_log_is_complete)) {
					continue;
				}
				if (Number(sel.task_log_item) == 0) {
    				continue;
	        	} 
				sel.task_log_is_complete = true;
				sel.task_log_completed_date = completedDate;
				taskLogScreen.enableSave = true;
			}
        }
        
        public function confirmCompleteTask(event:CloseEvent, completedDate:String):void {
        	var sel:Object = gridTaskLog.dataProvider.getItemAt(gridTaskLog.selectedIndex);
        	if (event.detail == Alert.NO) {
        		sel.task_log_is_complete = false;
        		gridTaskLog.dataProvider.itemUpdated(sel);
        		return;
        	}
        	var errors:String = "";
        	var i:int = gridTaskLog.selectedIndex + 1
        	if (Number(sel.task_log_item) == 0) {
        		errors += 'Row [' + i + ']: Activity can not be empty\n';
        	}
        	if (Number(sel.task_log_expense) == 3) {
    			errors += 'Row [' + i + ']: You can not complete task log whose expense type is Other \n';
    		}
        	errors += validateItem(sel, i);
        	if (errors.length > 0) {
        		sel.task_log_is_complete = false;
        		gridTaskLog.dataProvider.itemUpdated(sel);
        		alert.error(errors);
        		return;
        	}
        	sel.task_log_is_complete = true;
        	sel.task_log_completed_date = completedDate;
        	gridTaskLog.dataProvider.itemUpdated(sel);
        	taskLogScreen.enableSave = true;
        }
        
        //handle datagrid cell edit end event
        public function processData(event:AdvancedDataGridEvent):void {
        	if (event.reason == AdvancedDataGridEventReason.CANCELLED) {
        		return;
        	}
			var sel:Object = gridTaskLog.dataProvider.getItemAt(gridTaskLog.selectedIndex);
        	var colName:String = event.dataField;
        	if (colName == "task_log_is_complete") {
        		event.preventDefault();
        		return;
        	}
        	if (curValidator != null) {
	    		var vResult:ValidationResultEvent = curValidator.validate();
	    		if (vResult.type == ValidationResultEvent.INVALID) {
	    			event.preventDefault();
	    			return;
	    		}
        	}
        	taskLogScreen.enableSave = true;
			
        	if (event.rowIndex == (gridTaskLog.dataProvider.length - 1)) {
        		var emptyItem:Object = taskLogProxy.newTaskLog();
				gridTaskLog.dataProvider.addItem(emptyItem);
			}
        }
        
        public function comboBoxLabelFunction(item:Object, column:AdvancedDataGridColumn):String {
	    	switch (column.dataField) {
	    		case 'task_log_resource':
	    			return masterdataProxy.getUserById(item[column.dataField]);
	    		case 'task_log_item':
	    			return masterdataProxy.getTaskLogItemById(item[column.dataField]);	    		
	    		case 'task_log_currency':
	    			return masterdataProxy.getCurrencyById(item[column.dataField]);	    		
	    		case 'task_log_expense':
	    			return masterdataProxy.getExpenseTypeById(item[column.dataField]);	    		
	    		default:
	    			return '';
	    	}
    	}
    	
    	public function lfRowNum(item:Object, col:int):String {
        	if (Number(item.task_log_item) > 0) {
	        	return String(gridTaskLog.dataProvider.getItemIndex(item) + 1);
    		}
    		return "";
        }
        
        private function comboBoxItemLabelFunction(item:Object):String {
            return masterdataProxy.getItemById(item.qitem_item) as String;
        }
        
        private function comboBoxCargoTypeLabelFunction(item:Object):String {
            return masterdataProxy.getCargoTypeById(item.qitem_cargo_type);
        }
        
        private function comboBoxContainerLabelFunction(item:Object):String {
            return masterdataProxy.getContainerById(item.qitem_container);
        }
        
        private function comboBoxMethodLabelFunction(item:Object):String {
            return masterdataProxy.getMethodById(item.qitem_method);
        }
        
        private function lfTaskLogDate(item:Object, col:int):String {
        	var df:DateFormatter = new DateFormatter();
        	df.formatString = "DD/MM/YYYY";
            return df.format(DpUtils.parseDate(item.task_log_date));
        }
        
        private function lfTaskLogComplete(item:Object, col:int):String {
        	var df:DateFormatter = new DateFormatter();
        	df.formatString = "DD/MM/YYYY";
            return DpUtils.isTrue(item.task_log_is_complete) ? df.format(DpUtils.parseDate(item.task_log_completed_date)) : '';
        }
        
        private function comboBoxShippingTypeLabelFunction(item:Object):String {
            return masterdataProxy.getShippingTypeById(item.qitem_shipping_type);
        }
        
        private function comboBoxUnitLabelFunction(item:Object):String {
            return masterdataProxy.getUnitById(item.qitem_unit);
        }
        
        public function doRemoveTaskLog(selIndex:int):void {
        	if (selIndex < 0 || selIndex >= gridTaskLog.dataProvider.length) {
        		alert.error("You should select a row to remove");
        		return;
        	}
        	if (taskLogProxy.isTaskLogComplete(selIndex)) {
	    		alert.error("This task log is completed. You can not remove it!");
	    		return;
	    	}
        	alert.confirm("Do you want to remove row at [" + (selIndex + 1) + "]?", function(e:CloseEvent) {
        		if (e.detail != Alert.YES) {
        			return;
        		}
        		taskLogProxy.removeTaskLog(selIndex);
        		doValidate();
        		taskLogScreen.enableSave = true;
        		gridTaskLog.selectedIndex = -1;
        	});
        }
        
        function setupValidator(columnName:String, itemEditor:Object):void {
        	if (columnName == 'task_log_fuel') {
        		TextInput(itemEditor).restrict = "0-9,.";
        		taskLogScreen.quantityValidator.source = itemEditor;
        		taskLogScreen.quantityValidator.property = 'text';
        		taskLogScreen.quantityValidator.required = false;
        		curValidator = taskLogScreen.quantityValidator;
        	}
        	else if (columnName == 'task_log_amount_origin') {
        		TextInput(itemEditor).restrict = "0-9,.";
        		taskLogScreen.priceValidator.source = itemEditor;
        		taskLogScreen.priceValidator.property = 'text';
        		taskLogScreen.priceValidator.required = true;
        		curValidator = taskLogScreen.priceValidator;
        	}
        	else {
	        	curValidator = null;
        	}
        }
        
        private var curValidator:Validator;

	}	
}